```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JPA技术详解 - 现代Java持久化规范</title>
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        :root {
            --primary: #4F46E5;
            --primary-dark: #4338CA;
            --secondary: #10B981;
            --dark: #1F2937;
            --light: #F9FAFB;
            --gray: #6B7280;
            --accent: #EC4899;
        }
        
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: var(--dark);
            line-height: 1.6;
        }
        
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        
        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        
        .code-block {
            font-family: 'SFMono-Regular', Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
            background-color: #2d3748;
            color: #e2e8f0;
            border-radius: 0.375rem;
        }
        
        .section-title {
            position: relative;
            padding-left: 1.5rem;
        }
        
        .section-title:before {
            content: '';
            position: absolute;
            left: 0;
            top: 0.5rem;
            height: 1.5rem;
            width: 0.375rem;
            background-color: var(--primary);
            border-radius: 0.1875rem;
        }
        
        .comparison-table {
            border-collapse: separate;
            border-spacing: 0;
        }
        
        .comparison-table th {
            background-color: var(--primary);
            color: white;
        }
        
        .comparison-table td, .comparison-table th {
            padding: 0.75rem 1rem;
            border: 1px solid #e5e7eb;
        }
        
        .comparison-table tr:nth-child(even) {
            background-color: #f9fafb;
        }
        
        .comparison-table tr:hover {
            background-color: #f3f4f6;
        }
        
        .highlight {
            background-color: #fef3c7;
            padding: 0.25rem 0.5rem;
            border-radius: 0.25rem;
        }
        
        .diagram-container {
            background-color: white;
            border-radius: 0.5rem;
            padding: 1.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        
        .method-signature {
            background-color: #f3f4f6;
            border-left: 4px solid var(--primary);
            padding: 1rem;
            border-radius: 0 0.375rem 0.375rem 0;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:px-8">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4">Java持久化API(JPA)深度解析</h1>
                    <p class="text-xl mb-6 opacity-90">简化Java应用中的数据持久层开发</p>
                    <div class="flex flex-wrap gap-3">
                        <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full font-medium">ORM规范</span>
                        <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full font-medium">Spring Data</span>
                        <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full font-medium">Hibernate实现</span>
                    </div>
                </div>
                <div class="md:w-1/2 flex justify-center">
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1651305884247-e7abf171-54de-4b2d-ab00-55b6ab8191da.png" alt="JPA架构图" class="rounded-lg shadow-xl max-w-full h-auto">
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-6xl px-4 py-12">
        <!-- What is JPA Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">1. 什么是JPA</h2>
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <p class="text-lg mb-4">JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合ORM技术，解决Hibernate，TopLink，JDO等ORM框架各自为营的局面。</p>
                <div class="bg-blue-50 border-l-4 border-blue-500 p-4">
                    <p class="text-blue-800 font-medium"><i class="fas fa-info-circle mr-2"></i>简单来说，JPA是一套规范、标准，而Hibernate JPA是其中一种实现。</p>
                </div>
            </div>
            
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <p class="text-lg mb-4">与JDBC类似，JPA统一了Java应用程序访问ORM框架的规范。以前我们的应用程序直接使用ORM框架，如Hibernate、MyBatis。但是不同的ORM框架使用方法不一样，而JPA让我们以同样的方式访问不同的ORM框架。常用的框架是Hibernate JPA。</p>
                <div class="bg-red-50 border-l-4 border-red-500 p-4">
                    <p class="text-red-800 font-medium"><i class="fas fa-exclamation-triangle mr-2"></i>JPA是一个规范，不是框架，Hibernate JPA是JPA的一个实现</p>
                </div>
            </div>
        </section>

        <!-- JPA vs JDBC Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">2. JPA和JDBC区别及ORM</h2>
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <p class="text-lg mb-4">ORM(对象关系映射)映射元数据，支持XML和JDK注解两种元数据的形式</p>
                <div class="overflow-x-auto">
                    <table class="comparison-table w-full rounded-lg overflow-hidden">
                        <thead>
                            <tr>
                                <th class="text-left">实现</th>
                                <th class="text-left">JDBC</th>
                                <th class="text-left">JPA</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td class="font-medium">相同点</td>
                                <td colspan="2">都是一种规范，都可以操作数据库</td>
                            </tr>
                            <tr>
                                <td class="font-medium">不同点</td>
                                <td>
                                    <ul class="list-disc pl-5 space-y-1">
                                        <li>JDBC使用的是基于关系型数据库的标准SQL语言</li>
                                        <li>JDBC操作的是数据，将数据通过SQL语句直接传送到数据库中执行</li>
                                        <li>JDBC操作的数据是"瞬时"的，变量的值无法与数据库中的值保持一致</li>
                                    </ul>
                                </td>
                                <td>
                                    <ul class="list-disc pl-5 space-y-1">
                                        <li>JPA通过面向对象而非面向数据库的查询语言查询数据，避免程序的SQL语句紧密耦合</li>
                                        <li>JPA操作的是持久化对象，由底层持久化对象的数据更新到数据库中</li>
                                        <li>JPA操作的数据是可持久的，即持久化对象的数据属性的值是可以跟数据库中的值保持一致的</li>
                                    </ul>
                                </td>
                            </tr>
                            <tr>
                                <td class="font-medium">优点</td>
                                <td>性能高</td>
                                <td>性能低</td>
                            </tr>
                            <tr>
                                <td class="font-medium">缺点</td>
                                <td>需要手动实现ORM转换</td>
                                <td>JPA编写程序较为简单，实现了数据库的封装，程序员可以只关注entity部分而不需要理解数据库的关系</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            
            <!-- ORM Diagram -->
            <div class="diagram-container mb-6">
                <div class="mermaid">
                    flowchart LR
                    A[Java对象] --> B[ORM框架]
                    B --> C[关系数据库]
                    C --> B
                    B --> A
                </div>
            </div>
        </section>

        <!-- Spring Data Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">3. Spring Data 介绍</h2>
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <p class="text-lg mb-4">Spring Data 是Spring的一个子项目。用于简化数据库访问，支持<strong class="text-red-600">NoSQL</strong>和<strong class="text-red-600">关系数据存储</strong>。其主要目标是使数据库的访问变得方便快捷。</p>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6">
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <h3 class="font-bold text-lg mb-3 text-indigo-700 flex items-center">
                            <i class="fas fa-database mr-2"></i> SpringData支持的关系数据存储技术
                        </h3>
                        <ul class="space-y-2">
                            <li class="flex items-center"><i class="fas fa-check-circle text-green-500 mr-2"></i> JDBC</li>
                            <li class="flex items-center"><i class="fas fa-check-circle text-green-500 mr-2"></i> JPA</li>
                        </ul>
                    </div>
                    
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <h3 class="font-bold text-lg mb-3 text-indigo-700 flex items-center">
                            <i class="fas fa-server mr-2"></i> SpringData支持的NoSQL存储
                        </h3>
                        <ul class="space-y-2">
                            <li class="flex items-center"><i class="fas fa-check-circle text-green-500 mr-2"></i> MongoDB（文档数据库）</li>
                            <li class="flex items-center"><i class="fas fa-check-circle text-green-500 mr-2"></i> Redis（键/值存储）</li>
                            <li class="flex items-center"><i class="fas fa-check-circle text-green-500 mr-2"></i> Hbase（列族数据库）</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Spring Data JPA Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">4. Spring Data JPA介绍</h2>
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <p class="text-lg mb-4">SpringDataJPA致力于减少数据访问层(DAO)的开发量。开发者唯一要做的，就只是声明持久层的接口，其他都交给Spring Data JPA来帮你完成。</p>
                <div class="bg-yellow-50 border-l-4 border-yellow-500 p-4 mt-4">
                    <p class="text-yellow-800"><i class="fas fa-lightbulb mr-2"></i><strong>示例：</strong>当有一个userDao.findUserById()这样一个方法声明，Spring Data JPA会根据方法名自动实现查询逻辑，无需手动编写实现代码。</p>
                </div>
            </div>
        </section>

        <!-- Environment Setup Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">5. Spring Data JPA环境搭建</h2>
            
            <!-- 5.1 Import Jars -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <span class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center mr-3">5.1</span>
                    导入*.jar包
                </h3>
                <p class="mb-4">需要导入spring，hibernateJPA，SpringDataJPA的jar包</p>
            </div>
            
            <!-- 5.2 Define Interface -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <span class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center mr-3">5.2</span>
                    定义接口
                </h3>
                <div class="method-signature">
                    <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">public interface IStudentDao extends Repository&lt;Student, Integer&gt; {
    // 根据名字查询对象
    public Student findStudentByName(String name);
}</code></pre>
                </div>
            </div>
            
            <!-- 5.3 Spring Integration -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <span class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center mr-3">5.3</span>
                    Spring整合Spring Data JPA
                </h3>
                <p class="mb-4">在Spring的配置文件中需要添加SpringDataJPA的约束文件</p>
                <div class="method-signature">
                    <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">&lt;!-- 1.加载属性文件 location:指定文件文件的路径 --&gt;
&lt;context:property-placeholder location="classpath:jdbc.properties" /&gt;

&lt;!-- 2.数据源 --&gt;
&lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"&gt;
    &lt;property name="driverClass" value="${jdbc.driver}"&gt;&lt;/property&gt;
    &lt;property name="jdbcUrl" value="${jdbc.url}"&gt;&lt;/property&gt;
    &lt;property name="user" value="${jdbc.username}"&gt;&lt;/property&gt;
    &lt;property name="password" value="${jdbc.password}"&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;!-- 2. 配置 JPA 的 EntityManagerFactory --&gt;
&lt;bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
    &lt;!-- 数据源 --&gt;
    &lt;property name="dataSource" ref="dataSource"&gt;&lt;/property&gt;
    &lt;!-- 扫描实体类 --&gt;
    &lt;property name="packagesToScan" value="com.qf.entity"&gt;&lt;/property&gt;
    &lt;!--JPA供应商适配 --&gt;
    &lt;property name="jpaVendorAdapter"&gt;
        &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;&lt;/bean&gt;
    &lt;/property&gt;
    &lt;!-- 配置hibernate的其他属性 --&gt;
    &lt;property name="jpaProperties"&gt;
        &lt;props&gt;
            &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;
            &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;
            &lt;prop key="hibernate.format_sql"&gt;true&lt;/prop&gt;
            &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt;
        &lt;/props&gt;
    &lt;/property&gt;
&lt;/bean&gt;

&lt;!-- 事务管理器 --&gt;
&lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
    &lt;property name="entityManagerFactory" ref="entityManagerFactory" /&gt;
&lt;/bean&gt;

&lt;!-- Spring Data jpa的配置 
    base-package:dao层接口的包名
--&gt;
&lt;jpa:repositories base-package="com.qf.dao" entity-manager-factory-ref="entityManagerFactory"
    transaction-manager-ref="transactionManager" /&gt;

&lt;!-- 注册驱动 --&gt;
&lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;</code></pre>
                </div>
                <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mt-4">
                    <p class="text-blue-800"><i class="fas fa-info-circle mr-2"></i><strong>比较：</strong>LocalSessionFactoryBean和LocalContainerEntityManagerFactoryBean</p>
                    <p class="mt-2">LocalSessionFactoryBean 得到的是SessionFactory，SessionFactory用来创建session来进行数据库的操作。</p>
                    <p>LocalContainerEntityManagerFactoryBean得到的是EntityManagerFactory用来创建EntityManager来进行数据库的操作</p>
                </div>
            </div>
            
            <!-- 5.4 Entity Class -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <span class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center mr-3">5.4</span>
                    实体类对象
                </h3>
                <div class="method-signature">
                    <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Table(name="t_student")
@Entity
public class Student {
    /**
     * username:列名称
     * unique:是否唯一
     * nullable:是否为空
     * length:长度
     */
    @Column(name="username", unique=true,nullable=false,length=20)
    private String name;
    
    @Id // 主键
    @GeneratedValue(strategy=GenerationType.AUTO) // 主键生成策略
    private Integer id;
    
    private Integer age;
    
    private Date birthday;
}</code></pre>
                </div>
            </div>
            
            <!-- 5.5 Testing -->
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <span class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center mr-3">5.5</span>
                    测试
                </h3>
                <div class="method-signature">
                    <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">public class SpringDataHello {
    private ApplicationContext ctx = null;
    private IStudentDao studentDao;
    {
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        studentDao = ctx.getBean(IStudentDao.class);
    }
    @Test
    public void testFindStudentByName() {
        Student student = studentDao.findStudentByName("李四");
        System.out.println(studentDao.getClass());
        System.err.println(student); // 代理对象
    }
}</code></pre>
                </div>
            </div>
        </section>

        <!-- Repository Interface Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">6. Repository接口</h2>
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <ul class="list-disc pl-5 space-y-2 mb-4">
                    <li>Repository 是一个空接口，即是一个标识接口</li>
                    <li><strong>若我们定义的接口(dao层)继承了Repository或者子类，或者添加注解</strong>，则该接口会被IOC容器识别为一个Repository Bean(Proxy)放入到IOC容器中。在该类中定义的方法必须要满足一定规范
                        <ul class="list-decimal pl-5 mt-2 space-y-1">
                            <li>继承或者添加@RepositoryDefinition</li>
                            <li>要被JPA的注解扫到才会添加到Spring容器中</li>
                        </ul>
                    </li>
                    <li>也可以通过 @RepositoryDefinition 注解来替代继承 Repository 接口</li>
                </ul>
            </div>
            
            <!-- 6.1 Repository Subinterfaces -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4">6.1 Repository的子接口</h3>
                <div class="diagram-container">
                    <div class="mermaid">
                        classDiagram
                            Repository <|-- CrudRepository
                            CrudRepository <|-- PagingAndSortingRepository
                            PagingAndSortingRepository <|-- JpaRepository
                            Repository : +空接口
                            CrudRepository : +CRUD功能
                            PagingAndSortingRepository : +分页和排序
                            JpaRepository : +批量操作等实用功能
                            class JpaSpecificationExecutor {
                                +负责查询的接口
                            }
                    </div>
                </div>
            </div>
            
            <!-- 6.2 Method Naming Conventions -->
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <h3 class="text-xl font-bold mb-4">6.2 Repository类中方法定义的规范</h3>
                <ul class="list-disc pl-5 space-y-2 mb-4">
                    <li>不是随便声明的，而需要符合一定的规范</li>
                    <li>查询方法以 find | read | get 开头(比如 find、findBy、read、readBy、get、getBy)</li>
                    <li>涉及条件查询时，条件的属性用条件关键字连接，条件属性以首字母大写</li>
                    <li>支持属性的级联查询。若当前类有符合条件的属性，则优先使用，而不使用级联属性。若需要使用级联属性，则属性之间使用 _ 进行连接</li>
                </ul>
                
                <div class="bg-gray-50 p-4 rounded-lg mt-4">
                    <h4 class="font-bold mb-2">举例说明：</h4>
                    <p>比如 findByUserAddressZip()。框架在解析该方法时，首先剔除 findBy，然后对剩下的属性进行解析，详细规则如下（此处假设该方法针对的域对象为 AccountInfo 类型）：</p>
                    
                    <div class="mt-4">
                        <h5 class="font-medium mb-1">解析步骤：</h5>
                        <ol class="list-decimal pl-5 space-y-1">
                            <li>先判断 userAddressZip（根据POJO规范，首字母变为小写）是否为AccountInfo的一个属性，如果是，则表示根据该属性进行查询；如果没有该属性，继续第二步</li>
                            <li>从右往左截取第一个大写字母开头的字符串（此处为Zip），然后检查剩下的字符串(userAddress)是否为AccountInfo的一个属性，如果是，则表示根据该属性进行查询；如果没有该属性，则重复第二步</li>
                            <li>接着处理剩下部分（AddressZip），先判断user所对应的类型是否有addressZip属性，如果有，则表示该方法最终是根据"AccountInfo.user.addressZip"的取值进行查询；否则继续按照步骤2的规则从右往左截取</li>
                        </ol>
                    </div>
                    
                    <div class="mt-4">
                        <p><strong>特殊情况：</strong>比如AccountInfo包含一个user的属性，也有一个userAddress属性，则优先使用当前类的属性，而不使用级联属性。若需要使用级联属性，则属性之间使用_进行连接。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- JPQL Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">7. JPQL</h2>
            
            <!-- 7.1 What is JPQL -->
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <h3 class="text-xl font-bold mb-4">7.1 JPQL是什么</h3>
                <p class="mb-4">JPQL全称Java Persistence Query Language，操作的是类和属性，其实就是跟HQL一样的。</p>
            </div>
            
            <!-- 7.2 Supported Syntax -->
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <h3 class="text-xl font-bold mb-4">7.2 支持语法</h3>
                <p class="mb-4">JPQL提供的查询语法主要分为三类：</p>
                <ul class="list-disc pl-5 space-y-2">
                    <li>查询用的 SELECT 语法</li>
                    <li>更新用的 UPDATE 语法</li>
                    <li>删除用的 DELETE 语法</li>
                </ul>
            </div>
        </section>

        <!-- @Query Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">8. @Query查询</h2>
            <p class="mb-6">支持JPQL操作</p>
            
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <!-- JPQL Example -->
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-lg font-bold mb-3">JPQL查询</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Query(value="select s1 from Student s1 where s1.id = (select max(s2.id) from Student s2)")
public Student getMaxIdStudent();</code></pre>
                    </div>
                </div>
                
                <!-- Native SQL Example -->
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-lg font-bold mb-3">原生SQL查询</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Query(value="select s1.* from t_student s1 where s1.id = (select max(s2.id) from t_student s2)", nativeQuery=true)
public Student getMaxIdStudent();</code></pre>
                    </div>
                </div>
                
                <!-- Positional Parameters -->
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-lg font-bold mb-3">按顺序传递参数</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Query("select s from Student s where s.id = ?1 and s.name = ?2")
public Student findUser(Integer id, String name);</code></pre>
                    </div>
                </div>
                
                <!-- Named Parameters -->
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-lg font-bold mb-3">按名称传递参数</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Query("select s from Student s where s.id = :id and s.name = :name")
public Student findUser2(@Param("name")String name, @Param("id")Integer id);</code></pre>
                    </div>
                </div>
                
                <!-- Like Query -->
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-lg font-bold mb-3">模糊查询</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Query("select s from Student s where s.name like %:name%")
public Student findUser3(@Param("name")String name);</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- @Modifying Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">9. @Modifying</h2>
            <div class="bg-white rounded-lg shadow-md p-6 card">
                <div class="method-signature">
                    <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">@Modifying
@Query("update Student s set s.name = :name where s.id =:id")
public int updateUserUsername(@Param("id")Integer id, @Param("name")String name);</code></pre>
                </div>
                
                <div class="bg-red-50 border-l-4 border-red-500 p-4 mt-4">
                    <h4 class="font-bold text-red-800 mb-2"><i class="fas fa-exclamation-circle mr-2"></i>注意事项：</h4>
                    <ul class="list-disc pl-5 space-y-1 text-red-800">
                        <li>可以通过JPQL完成DELETE和UPDATE操作，但是不能完成INSERT，因为JPQL不支持INSERT</li>
                        <li>在@Query中编写更新语句必须要用@Modifying注解修饰，要通知SpringDataJPA这是一个更新操作</li>
                        <li>在做更新操作的时候需要事务</li>
                        <li>默认情况下SpringDateJPA给每个方法都加事务，它们都是只读事务，不能完成更新</li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- JpaSpecificationExecutor Section -->
        <section class="mb-16">
            <h2 class="section-title text-2xl md:text-3xl font-bold mb-6">10. JpaSpecificationExecutor</h2>
            <div class="bg-white rounded-lg shadow-md p-6 mb-6 card">
                <p class="mb-4">不属于Repository体系，实现一组JPA Criteria查询相关的方法</p>
                
                <div class="bg-gray-50 p-4 rounded-lg">
                    <h3 class="font-bold mb-2">Repository接口</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">public interface IUserDao extends JpaRepository&lt;User, Integer&gt;, JpaSpecificationExecutor&lt;User&gt; {
}</code></pre>
                    </div>
                </div>
                
                <div class="bg-gray-50 p-4 rounded-lg mt-4">
                    <h3 class="font-bold mb-2">调用查询方法</h3>
                    <div class="method-signature">
                        <pre class="code-block p-4 rounded-md overflow-x-auto"><code class="text-sm">Pageable pageable = new PageRequest(2, 4);
Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
    /**
     * root: 代表查询的实体类
     * query: 查询条件
     * cb: 用于创建Criteria相关对象的工厂.可以从中获取到Predicate对象
     * @return: Predicate类型,代表一个查询条件
     */
    @Override
    public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; query, CriteriaBuilder cb) {
        Path path1 = root.get("id");
        Path path2 = root.get("username");
        Path path3 = root.get("password");
        // Path&lt;Object&gt; path4 = root.get("user").get("id"); // 级联查询
        Predicate predicate = cb.equal(path1, 5);
        // Predicate predicate = cb.and(cb.gt(path2, 2),cb.gt(path3,3)); // 多条件查询
        return predicate;
    }
};
Page&lt;User&gt; page = userDao.findAll(spec, pageable);</code></pre>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```